package com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.nyk;

import com.alibaba.cirtus.ots.application.adapter.ability.model.sdo.OrgSalesIdSDO;
import com.alibaba.cirtus.ots.application.adapter.ability.model.sdo.SalesPlanNykSDO;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByCodes2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByCodes2Response;
import com.epoch.app.bcorder.model.dto.ScItemSDO;
import com.epoch.app.bcorder.model.dto.SearchScItemRequest;
import com.epoch.app.bcorder.salesplannyk.dto.LoadListSalesPlanNykListRequest;
import com.epoch.app.bcorder.salesplannyk.model.SalesPlanNyk;
import com.epoch.app.bcorder.salesplannyk.service.SalesPlanNykService;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.otsapplicationadaptersdk.model.dto.RestNykMonthPlanDataRequest;
import com.epoch.app.otsapplicationadaptersdk.nyk.NykMonthPlan;
import com.epoch.app.otsapplicationadaptersdk.nyk.NykMonthPlanPageData;
import com.epoch.app.otsapplicationadaptersdk.nyk.NykMonthPlanResponse;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnykmonthplan.dto.DoHandlerRequest;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnykmonthplan.dto.DoHandlerResponse;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnykmonthplan.service.MnNykMonthPlanService;
import com.epoch.app.otsapplicationadaptersdk.service.NykService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zhoubc
 * @description: 牛要客月度计划数据同步
 * @date 2021/11/8 21:50
 */
@Component
public class MnNykMonthPlanV2ServiceImpl implements MnNykMonthPlanService {
    private final Log log = Log.getLogger(MnNykMonthPlanV2ServiceImpl.class);

    @Resource
    private NykService nykService;

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private SalesPlanNykService salesPlanNykService;

    @ProcessInvoker(remark = "MnNykMonthPlanService", errorCode = "OTS-02-007-00-16-999", printLog = true)
    @Override
    public DoHandlerResponse doHandler(DoHandlerRequest doHandlerRequest) {
        log.error("MnNykMonthPlanServiceImpl.doHandler入参：" + JSONObject.toJSONString(doHandlerRequest));
        RestNykMonthPlanDataRequest request = buildRequest(doHandlerRequest);
        NykMonthPlanResponse response = nykService.restNykMonthPlanData(request);
        log.error("MnNykMonthPlanServiceImpl.doHandler查询出：" + JSONObject.toJSONString(request));
        DoHandlerResponse doHandlerResponse = new DoHandlerResponse();
        if (Objects.isNull(response)) {
            log.error("MnNykMonthPlanServiceImpl#doHandler_fail 没有查到同步数据");
            doHandlerResponse.setSuccess(false);
            doHandlerResponse.setMessage("没有查到同步数据");
            return doHandlerResponse;
        }
        if (Objects.nonNull(response.getSuccess()) && !response.getSuccess()) {
            log.error("MnNykMonthPlanServiceImpl#doHandler_fail " + doHandlerResponse.getMessage());
            doHandlerResponse.setSuccess(false);
            doHandlerResponse.setMessage("查询失败,message：" + doHandlerResponse.getMessage());
            return doHandlerResponse;
        }

        NykMonthPlanPageData data = response.getData();
        if (Objects.isNull(data) || CollectionUtils.isEmpty(data.getRecords())) {
            log.error("MnNykMonthPlanServiceImpl#doHandler_fail 该月没有数据");
            doHandlerResponse.setSuccess(true);
            doHandlerResponse.setMessage("该月没有数据");
            doHandlerResponse.setSuccesScItemCodes(Lists.newArrayList());
            doHandlerResponse.setFailScItemCodes(Lists.newArrayList());
            return doHandlerResponse;
        }

        List<String> successItemCodes = Lists.newArrayList();
        List<String> failItemCodes = Lists.newArrayList();
        for (int i = 1; i <= data.getPages(); i++) {
            request.setCurrent(String.valueOf(i));
            NykMonthPlanResponse pageResponse = nykService.restNykMonthPlanData(request);
            log.error("MnNykMonthPlanServiceImpl.doHandler查询结果：" + JSONObject.toJSONString(pageResponse));
            List<NykMonthPlan> records = pageResponse.getData().getRecords();
            try {
                syncCurrentPage(records, successItemCodes, failItemCodes);
            } catch (Exception e) {
                log.error("MnNykMonthPlanServiceImpl#doHandler_fail 异常信息:{}" , e);
            }
        }
        List<String> successes = successItemCodes.stream().distinct().collect(Collectors.toList());
        List<String> failures = failItemCodes.stream().distinct().collect(Collectors.toList());
        doHandlerResponse.setSuccesScItemCodes(successes);
        doHandlerResponse.setFailScItemCodes(failures);
        doHandlerResponse.setSuccess(true);
        doHandlerResponse.setMessage("同步完成");
        return doHandlerResponse;
    }

    private RestNykMonthPlanDataRequest buildRequest(DoHandlerRequest doHandlerRequest) {
        RestNykMonthPlanDataRequest restNykMonthPlanDataRequest = new RestNykMonthPlanDataRequest();
        restNykMonthPlanDataRequest.setCurrent(doHandlerRequest.getCurrent());
        restNykMonthPlanDataRequest.setSize(doHandlerRequest.getSize());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(doHandlerRequest.getQueryDate())) {
            restNykMonthPlanDataRequest.setQueryDate(doHandlerRequest.getQueryDate());
        }
        return restNykMonthPlanDataRequest;
    }

    private void syncCurrentPage(List<NykMonthPlan> records, List<String> successItemCodes, List<String> failItemCodes) {
        //1、批量转换货品编码、平台没有的货品或者禁用的货品跳过
        List<String> outerIds = records.stream().map(it -> {
            String itemCode = it.getItemCode();
            if (itemCode.length() >= 12) {
                return StringUtils.substring(itemCode, itemCode.length() - 12);
            }
            return itemCode;
        }).collect(Collectors.toList());
        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
        Map searchReqDTO = new HashMap();
        searchReqDTO.put("outerIdList", outerIds);
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        searchScItemRequest.setPageNum(1);
        searchScItemRequest.setPageSize(2000);
        Result<List<ScItemSDO>> scItemResult = baseDataService.searchScItem(searchScItemRequest);
        log.error("MnNykMonthPlanServiceImpl.syncCurrentPage查询结果：" + JSONObject.toJSONString(scItemResult));
        if (Objects.isNull(scItemResult) || CollectionUtils.isEmpty(scItemResult.getResult())) {
            return;
        }
        //获取业务单元ID与销售组织编码
        OrgSalesIdSDO orgSalesIdSDO = buildOrgSalesIdSDO();
        //2、新增或修改(业务单元默认固定垂直重客)
        Map<String, ScItemSDO> scItemSDOMap = scItemResult.getResult().stream().collect(Collectors.toMap(ScItemSDO::getOuterId, it -> it));
        for (NykMonthPlan monthPlan : records) {
            ScItemSDO scItemSDO = scItemSDOMap.get(monthPlan.getItemCode());
            if (Objects.isNull(scItemSDO)) {
                failItemCodes.add(monthPlan.getItemCode());
                continue;
            }
            SalesPlanNykSDO salesPlanNykSDO = buildSalesPlanNykSDO(monthPlan, orgSalesIdSDO);
            salesPlanNykSDO.setScItemId(scItemSDO.getScItemId());
            // 查出唯一数据,唯一条件：牛要客ID
            LoadListSalesPlanNykListRequest build = LoadListSalesPlanNykListRequest.builder().build();
            build.setSalesPlanNykId(salesPlanNykSDO.getSalesPlanNykId());
            //新增或修改
            Result<List<SalesPlanNyk>> listResult = salesPlanNykService.loadListSalesPlanNykList(build);
            if (CollectionUtils.isEmpty(listResult.getResult())) {
                SalesPlanNyk salesPlanNyk = new SalesPlanNyk();
                BeanUtils.copyProperties(salesPlanNykSDO, salesPlanNyk);
//                salesPlanNyk.setGmtCreate(new Date());
//                salesPlanNyk.setGmtModified(new Date());
                salesPlanNyk.setGmt_create(new Date());
                salesPlanNyk.setGmt_modified(new Date());
                salesPlanNykService.createSalesPlanNyk(salesPlanNyk);
            } else {
                SalesPlanNyk salesPlan = listResult.getResult().stream().findFirst().get();

                SalesPlanNyk salesPlanNyk = new SalesPlanNyk();
                BeanUtils.copyProperties(salesPlanNykSDO, salesPlanNyk);
                salesPlanNyk.setId(salesPlan.getId());
//                salesPlanNyk.setGmtModified(new Date());
                salesPlanNyk.setGmt_modified(new Date());
                salesPlanNykService.updateSalesPlanNyk(salesPlanNyk);
            }
            successItemCodes.add(monthPlan.getItemCode());
        }
    }

    private OrgSalesIdSDO buildOrgSalesIdSDO() {
        OrgSalesIdSDO orgSalesIdSDO = new OrgSalesIdSDO();
        String orgSalesBusinessUnitCode = "1900027440";
        String orgSaleOrganizationCode = "6140";
        BaselineGetOrganizationByCodes2Response byCodes2Response1 = baseDataService.baselineGetOrganizationByCodes2(BaselineGetOrganizationByCodes2Request.builder().ids(Lists.newArrayList(orgSalesBusinessUnitCode)).build());
        BaselineGetOrganizationByCodes2Response byCodes2Response2 = baseDataService.baselineGetOrganizationByCodes2(BaselineGetOrganizationByCodes2Request.builder().ids(Lists.newArrayList(orgSaleOrganizationCode)).build());
        if (CollectionUtils.isNotEmpty(byCodes2Response1.getResult())) {
            String orgSalesBusinessUnitId = byCodes2Response1.getResult().get(0).getId();
            orgSalesIdSDO.setOrgSalesBusinessUnitId(orgSalesBusinessUnitId);
        }
        if (CollectionUtils.isNotEmpty(byCodes2Response2.getResult())) {
            String orgSaleOrganizationId = byCodes2Response2.getResult().get(0).getId();
            orgSalesIdSDO.setOrgSaleOrganizationId(orgSaleOrganizationId);
        }
        return orgSalesIdSDO;
    }


    private SalesPlanNykSDO buildSalesPlanNykSDO(NykMonthPlan monthPlan, OrgSalesIdSDO orgSalesIdSDO) {
        long planTime = getPlanTime(monthPlan);
        SalesPlanNykSDO salesPlanNykSDO = new SalesPlanNykSDO();
        salesPlanNykSDO.setPlanTime(String.valueOf(planTime));
        salesPlanNykSDO.setAdjust(monthPlan.getAdjust());
        salesPlanNykSDO.setFinaly(monthPlan.getFinaly());
        salesPlanNykSDO.setFirstWeek(monthPlan.getFirstWeek());
        salesPlanNykSDO.setSecondWeek(monthPlan.getSecondWeek());
        salesPlanNykSDO.setThirdWeek(monthPlan.getThirdWeek());
        salesPlanNykSDO.setFourthWeek(monthPlan.getFourthWeek());
        salesPlanNykSDO.setConfirmed(monthPlan.getConfirmed());
        salesPlanNykSDO.setOrgSalesBusinessUnitCode("");
        salesPlanNykSDO.setRevise(monthPlan.getRevise());
        salesPlanNykSDO.setPredict(monthPlan.getPredict());
        salesPlanNykSDO.setScItemName(monthPlan.getItemName());
        salesPlanNykSDO.setOutCreateDate(monthPlan.getCreateTime());
        salesPlanNykSDO.setRetailer(monthPlan.getRetailer());
        salesPlanNykSDO.setRegion(monthPlan.getRegion());
        salesPlanNykSDO.setStoreName(monthPlan.getStoreCode());
        salesPlanNykSDO.setWhseCode(monthPlan.getWhseCode());
        salesPlanNykSDO.setWhseName(monthPlan.getWhseName());
        salesPlanNykSDO.setOuterId(monthPlan.getItemCode());
        salesPlanNykSDO.setSalesPlanNykId(monthPlan.getId());
        salesPlanNykSDO.setOrgSalesBusinessUnitCode(orgSalesIdSDO.getOrgSalesBusinessUnitId());
        salesPlanNykSDO.setOrgSaleOrganizationCode(orgSalesIdSDO.getOrgSaleOrganizationId());
        return salesPlanNykSDO;
    }

    private long getPlanTime(NykMonthPlan nykMonthPlan) {
        SimpleDateFormat yyyyMM = new SimpleDateFormat("yyyyMM");
        long time = 0;
        try {
            time = yyyyMM.parse(nykMonthPlan.getMonth()).getTime();
        } catch (ParseException e) {
            log.error("日期转换失败");
        }
        return time;
    }

}
